package com.ihr360.excel.aspect;

import com.ihr360.commons.exception.Ihr360SpreadSheetAsynException;
import com.ihr360.commons.exception.Ihr360SpreadSheetInterruptException;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.excel.annotation.InterruptIgnore;
import com.ihr360.excel.model.type.JournalType;
import com.ihr360.excel.service.ExcelService;
import com.ihr360.excel.vo.ProgressContext;
import com.ihr360.sharedservice.api.DataCacheService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 流程中断后，拦截请求切面
 */
@Aspect
@Component
public class InterruptRequestAspect {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private DataCacheService dataCacheService;

    @Autowired
    private ExcelService excelService;

    @Pointcut("execution(* com.ihr360.excel.service.impl..*(..))")
    public void canInterruptMethodSheetMethod() {

    }
    @Pointcut("execution(* com.ihr360.excel.service..*(..))")
    public void allSpreadSheetMethod() {

    }


    @Before("canInterruptMethodSheetMethod()")
    public void handleInterruptMethod(JoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        Object target = joinPoint.getTarget();
        Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
        Method method = target.getClass().getMethod(methodName, parameterTypes);

        InterruptIgnore interruptIgnore = method.getAnnotation(InterruptIgnore.class);
        if (interruptIgnore != null) {
            return;
        }

        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            ProgressContext progressContext = null;
            for (Object arg : args) {
                if (arg instanceof ProgressContext) {
                    progressContext = (ProgressContext) arg;
                    break;
                }
            }
            if (progressContext != null) {
                String progress = dataCacheService.get(progressContext.getProgressKey());
                //进度不存在
                if (StringUtils.isEmpty(progress)) {
                    throw new Ihr360SpreadSheetInterruptException("流程中断异常");
                }
            }
        }
    }


    @AfterThrowing(pointcut = "allSpreadSheetMethod()", throwing = "exception")
    public void handleInterruptMethod(Throwable exception) throws Throwable {
        if (exception instanceof Ihr360SpreadSheetAsynException) {
            Ihr360SpreadSheetAsynException spreadSheetAsynException = (Ihr360SpreadSheetAsynException) exception;
            ProgressContext progressContext = ProgressContext.getInstanceByProgressKey(spreadSheetAsynException.getProgressKey());
            excelService.saveExcelProcessorJournal(progressContext, exception.getMessage(), spreadSheetAsynException.getMsgKey(),
                    spreadSheetAsynException.getArgs(), JournalType.INTERRUPTLOG);
        } else if (exception instanceof Ihr360SpreadSheetInterruptException) {
            logger.info(exception.getMessage());
        } else {
            throw exception;
        }
    }


}
